import $ from "./jq.extend";
import config from "../Config";
import apiCore from "./ApiCore";
import api from "../ApiConnector.js";
import gx from "../gx.js";

//全局记录是否正在刷新token
let isRefreshToken = false;

//记录在报401时有多少个请求需要重新执行
let refreshReqArr = [];

const app = {
    api: api,

    //登录
    Login(loginObj, options) {
        let opts = {};

        $.extend(opts, options);

        apiCore.CallAuthentication(loginObj, {
            success: (res) => {
                if (res.statusCode == 200) {
                    opts.success && opts.success(res.data);
                } else if (res.data && res.data.error_description) {
                    this.Tips({ title: res.data.error_description });
                } else {
                    this.Tips({ title: "登录出错！" });
                }
            },
            fail: () => {
                this.Tips({ title: "网络请求失败！" });
            },
            complete: () => {
                uni.hideLoading();
            },
        });
    },

    //登出
    Logout() {
        this.RemoveStoredData();
        this.RedirectLogin();
    },

    //移除当前用户信息
    RemoveStoredData() {
        uni.clearStorageSync();
    },

    //重定向到登录页
    RedirectLogin() {
        uni.reLaunch({ url: "/pages/login/login" });
    },

    //从Cookie中得到当前登录用户的Me信息
    GetMe() {
        return uni.getStorageSync(config.MeKey);
    },

    //从Cookie中得到Token信息
    GetToken() {
        return uni.getStorageSync(config.TokenKey);
    },

    //调用接口更新Cookie中的Me信息
    UpdateMe(opts) {
        this.CallApi(this.api.Me, {
            success: (res) => {
                opts && opts.success && opts.success(res);
            },
            fail: () => {
                opts && opts.fail && opts.fail();
            },
            exception: () => {
                opts && opts.fail && opts.fail();
            },
        });
        // this.CallApi(this.api.GetMePermissionIDs, {
        //     success: (res) => {
        //         store.commit('SetPermission', res);
        //         opts && opts.success && opts.success(res);
        //     },
        //     fail: () => {
        //         opts && opts.fail && opts.fail();
        //     },
        //     exception: () => {
        //         opts && opts.fail && opts.fail();
        //     }
        // });
        // this.CallApi(this.api.ConfigSetting.GetConfig(), {
        //     success: (res) => {
        //         store.commit('SetConfigSetting', res);
        //         opts && opts.success && opts.success(res);
        //     },
        //     fail: () => {
        //         opts && opts.fail && opts.fail();
        //     },
        //     exception: () => {
        //         opts && opts.fail && opts.fail();
        //     }
        // });
    },

    //获取七牛token
    GetQiniuToken() {
        this.CallApi(this.api.GetQiniuToken, {
            success: (res) => {
                uni.setStorageSync(config.QiniuTokenKey, res);
            },
        });
    },

    //判断当前是否为登录状态
    IsLogin() {
        let token = this.GetToken();
        let me = this.GetMe();

        if (!gx.IsEmpty(token) && !gx.IsEmpty(me)) {
            return true;
        } else {
            return false;
        }
    },

    //统一的调用Api的方法
    CallApi(api, options) {
        if (!api) {
            throw new Error("未提供有效的api信息");
        }

        let that = this;

        let opts = {
            data: null,
            method: "get",
            hasToken: true,
            header: {
                "Content-Type": "Application/json",
            },
        };

        $.extend(opts, api);
        $.extend(opts, options);

        let onSuccess = opts.success;
        let onFail = opts.onFail;
        let onException = opts.exception;

        opts.success = (res) => {
            switch (res.statusCode) {
                case 200:
                    switch (res.data.code) {
                        case 0:
                            //api完全执行成功
                            onSuccess && onSuccess(res.data.data, res.data);
                            break;

                        case 500:
                            //api执行报异常
                            if (onException) {
                                onException(res);
                            } else {
                                this.Tips({ title: "系统异常！" });
                            }
                            break;

                        default:
                            //api非完全执行成功
                            if (onFail) {
                                onFail(res);
                            } else {
                                this.Tips({ title: res.data.msg });
                            }
                            break;
                    }
                    break;

                case 401:
                    if (!isRefreshToken) {
                        isRefreshToken = true;
                        refreshReqArr.push(opts);

                        //调用刷新token接口
                        apiCore.CallRefreshToken({
                            success: (res) => {
                                // //把新的token存储到cookie中
                                uni.setStorageSync(config.TokenKey, res.data);

                                //循环执行还未执行的请求
                                refreshReqArr.forEach((item) => apiCore.Call(item));
                                refreshReqArr = [];
                                isRefreshToken = false;
                            },
                            fail: () => {
                                refreshReqArr = [];
                                isRefreshToken = false;

                                this.Alert({
                                    msg: "会话异常，请重新登录！",
                                    success: () => {
                                        if (res.confirm) {
                                            this.Logout();
                                        }
                                    },
                                });
                            },
                        });
                    } else {
                        //正在刷新token，先记录下未完成的请求信息
                        refreshReqArr.push(opts);
                    }
                    break;

                default:
                    break;
            }
        };

        opts.fail = (res) => {
            this.Tips({ title: "网络请求失败！" });
        };

        opts.complete = (res) => {
            uni.hideLoading();
            uni.stopPullDownRefresh();
        };

        apiCore.Call(opts);
    },

    //单文件上传到本地
    Upload(files) {
        return new Promise((resolve) => {
            let _token = uni.getStorageSync(config.TokenKey);
            let file = files[0];

            let opts = {
                url: config.ApiUrl + "/Upload",
                formData: {
                    file: file,
                },
                header: {
                    Authorization: "Bearer " + _token.access_token,
                },
                success: (res) => {
                    let data = JSON.parse(res.data);
                    resolve(data.data.url);
                },
                fail: () => {},
            };
            uni.uploadFile(opts);
        });
    },

    //多文件上传到本地
    Uploads(files) {
        return new Promise((resolve) => {
            let _token = uni.getStorageSync(config.TokenKey);
            let arr = new Array();
            let cnt = 0;

            console.log(files);

            for (let i = 0; i < files.length; i++) {
                let file = files[i];

                let opts = {
                    url: config.ApiUrl + "/Upload",
                    formData: {
                        file: file,
                    },
                    header: {
                        Authorization: "Bearer " + _token.access_token,
                    },
                    success: (res) => {
                        console.log(res);
                        let data = JSON.parse(res.data);
                        arr.push({
                            fileName: data.data.fileName,
                            url: data.data.url,
                        });
                        cnt++;
                        if (cnt == files.length) {
                            resolve(arr);
                        }
                    },
                    fail: () => {
                        console.log("fail");
                        cnt++;
                        if (cnt == files.length) {
                            resolve(arr);
                        }
                    },
                };
                uni.uploadFile(opts);
            }
        });
    },

    //单文件上传到七牛云
    UploadQiniu(files) {
        return new Promise((resolve) => {
            let _token = uni.getStorageSync(config.QiniuTokenKey);
            let file = files[0];

            let opts = {
                url: _token.bucketArea,
                formData: {
                    token: _token.token,
                    domain: _token.domain,
                    key: gx.GenerateFileName(file),
                    file: file,
                },
                headers: {
                    "Content-Type": "multipart/form-data",
                },
                success: (res) => {
                    let data = JSON.parse(res.data);
                    let url = _token.domain + "/" + data.key;
                    resolve(url);
                },
                fail: () => {},
            };
            uni.uploadFile(opts);
        });
    },

    //多文件上传到七牛云
    UploadQinius(files) {
        return new Promise((resolve) => {
            let _token = uni.getStorageSync(config.QiniuTokenKey);
            let arr = new Array();
            let cnt = 0;

            for (let i = 0; i < files.length; i++) {
                let file = files[i];

                let opts = {
                    url: _token.bucketArea,
                    formData: {
                        token: _token.token,
                        domain: _token.domain,
                        key: gx.GenerateFileName(file),
                        file: file,
                    },
                    headers: {
                        "Content-Type": "multipart/form-data",
                    },
                    success: (res) => {
                        let data = JSON.parse(res.data);
                        let url = _token.domain + "/" + data.key;
                        arr.push({
                            sn: i,
                            url: url,
                        });
                        cnt++;
                        if (cnt == files.length) {
                            resolve(arr);
                        }
                    },
                    fail: () => {
                        cnt++;
                        if (cnt == files.length) {
                            resolve(arr);
                        }
                    },
                };
                uni.uploadFile(opts);
            }
        });
    },

    /**
     * 显示加载中效果，默认在callApi方法请求前调用
     */
    ShowLoading: function (msg) {
        // App平台调用此API时会在屏幕中间悬浮显示loading
        // uni.showNavigationBarLoading();
        uni.showLoading({
            title: msg || "加载中",
            mask: true,
        });
    },

    /**
     * 隐藏加载中效果，默认在callApi方法的success第一行中关闭
     */
    HideLoading: function () {
        // App平台调用此API时会在屏幕中间悬浮显示loading
        // uni.hideNavigationBarLoading();
        uni.hideLoading();
    },

    //无按钮的提示信息
    Tips(options) {
        let opts = {
            title: "",
            icon: "error",
            mask: true,
            duration: 2000,
        };

        $.extend(opts, options);

        uni.showToast(opts);
    },

    //单按钮提示框
    Alert(options) {
        let opts = {
            title: "提示",
            msg: "",
            showCancel: false,
            confirmText: "确定",
        };

        $.extend(opts, options);

        opts.content = opts.msg;

        uni.showModal(opts);
    },

    //两个按钮的提示框
    Confirm(options) {
        let opts = {
            title: "提示",
            msg: "",
            showCancel: true,
            confirmText: "确定",
        };

        $.extend(opts, options);

        opts.content = opts.msg;

        uni.showModal(opts);
    },
};

module.exports = app;
